`include "vga_param.v"

// `define USE_LINE
// `define USE_SHIFT
`define USE_GRID

module vga_display_ctrl(
    //Inputs
     input clk
    ,input rst_n
    ,input [11:0] pos_x
    ,input [11:0] pos_y
    ,input [3:0] vga_dis_mode
    //Outputs
    ,output reg [15:0] rgb_data
);


localparam MAX_X = `VGA_WIDTH;
localparam MAX_Y = `VGA_HEIGHT;
localparam X1 = MAX_X/5;
localparam X2 = MAX_X/5*2;
localparam X3 = MAX_X/5*3;
localparam X4 = MAX_X/5*4;

localparam Y1 = MAX_Y/5;
localparam Y2 = MAX_Y/5*2;
localparam Y3 = MAX_Y/5*3;
localparam Y4 = MAX_Y/5*4;

localparam CLR_WHITE = 16'hffff;
localparam CLR_BLACK = 16'h0;
localparam CLR_RED   = {5'h1f, 6'h00, 5'h00};
localparam CLR_GREEN = {5'h00, 6'h3f, 5'h00};
localparam CLR_BLUE  = {5'h00, 6'h00, 5'h1f};

`ifdef USE_LINE

    always @ (posedge clk) begin
        if(!rst_n)
            rgb_data <= 'h0;
        else begin
            
            case (pos_x)
                1 : rgb_data <= CLR_BLUE;
                X1: rgb_data <= CLR_GREEN;
                X2: rgb_data <= CLR_RED;
                X3: rgb_data <= CLR_BLACK;
                X4: rgb_data <= CLR_WHITE;
            endcase
            /*
            case (pos_y)
                1 : rgb_data <= CLR_BLUE;
                Y1: rgb_data <= CLR_GREEN;
                Y2: rgb_data <= CLR_WHITE;
                Y3: rgb_data <= CLR_BLACK;
                Y4: rgb_data <= CLR_RED;
            endcase
            */
        end
    end

`elsif USE_SHIFT

    reg [15:0] rgb_data_reg [4:0];

    wire frame_update = (pos_x == `VGA_WIDTH-1 & pos_y == `VGA_HEIGHT-1);

    always @ (posedge clk) begin
        if(!rst_n) begin
            rgb_data_reg[0] <= CLR_BLUE;
            rgb_data_reg[1] <= CLR_GREEN;
            rgb_data_reg[2] <= CLR_RED;
            rgb_data_reg[3] <= CLR_WHITE;
            rgb_data_reg[4] <= CLR_BLACK;
        end
        else if(frame_update) begin
            rgb_data_reg[0] <= rgb_data_reg[1];
            rgb_data_reg[1] <= rgb_data_reg[2];
            rgb_data_reg[2] <= rgb_data_reg[3];
            rgb_data_reg[3] <= rgb_data_reg[4];
            rgb_data_reg[4] <= rgb_data_reg[0];
        end
    end

    always @ (posedge clk) begin
        if(!rst_n)
            rgb_data <= 'h0;
        else begin
            
            case (pos_x)
                0 : rgb_data <= rgb_data_reg[0];
                X1: rgb_data <= rgb_data_reg[1];
                X2: rgb_data <= rgb_data_reg[2];
                X3: rgb_data <= rgb_data_reg[3];
                X4: rgb_data <= rgb_data_reg[4];
            endcase
            /*
            case (pos_y)
                0 : rgb_data <= rgb_data_reg[0];
                Y1: rgb_data <= rgb_data_reg[1];
                Y2: rgb_data <= rgb_data_reg[2];
                Y3: rgb_data <= rgb_data_reg[3];
                Y4: rgb_data <= rgb_data_reg[4];
            endcase
            */
        end
    end

`elsif USE_GRID

    reg [15:0] grid_data_1;
    reg [15:0] grid_data_2;
    reg [15:0] bar_data;

    always @(posedge clk) begin
        if(!rst_n)
            grid_data_1 <= 0;
        else if(pos_x[4] ^ pos_y[4])            //产生格子1图像
            grid_data_1<= 0;
        else
            grid_data_1<= 'hffff;
        
        if(!rst_n)
            grid_data_2 <= 0;
        else if(pos_x[6] ^ pos_y[6])            //产生格子2图像
            grid_data_2 <= 'h0;
        else
            grid_data_2 <= 'hffff;
    end

    always @(posedge clk) begin
        if(!rst_n)
            bar_data <= 'h0;
        else begin
            case(pos_x)
                'd300 : bar_data <= 'hf800;
                'd420 : bar_data <= 'h07e0;
                'd540 : bar_data <= 'h001f;
                'd660 : bar_data <= 'hf81f;
                'd780 : bar_data <= 'hffe0;
                'd900 : bar_data <= 'h07ff;
                'd1020: bar_data <= 'hffff;
                'd1140: bar_data <= 'hfc00;
                'd1260: bar_data <= 'h0000;
            endcase
        end
    end
    
    always @(posedge clk) begin
        if(!rst_n)
            rgb_data <= 'h0;
        else begin
            case(vga_dis_mode)
                'd0 : rgb_data <= 'h0000;     //black
                'd1 : rgb_data <= 'hffff;     //white
                'd2 : rgb_data <= 16'b11111_000000_00000;  //red
                'd3 : rgb_data <= 16'b00000_111111_00000;  //green
                'd4 : rgb_data <= 16'b00000_000000_11111;  //blue
                'd5 : rgb_data <= grid_data_1[15:0]; //grid_1
                'd6 : rgb_data <= grid_data_2[15:0]; //grid_2
                'd7 : rgb_data <= {pos_x[6:2], pos_x[6:1], pos_x[6:2]}; //VGA显示水平渐变色
                'd8 : rgb_data <= {pos_y[6:2], pos_y[6:1], pos_y[6:2]}; //VGA显示垂直渐变色
                'd9 : rgb_data <= {pos_x[6:2], 6'd0, 5'd0}; //VGA显示红水平渐变色
                'd10: rgb_data <= {5'b0, pos_x[6:1], 5'b0}; //VGA显示绿水平渐变色
                'd11: rgb_data <= {5'b0, 6'b0, pos_x[6:2]}; //VGA显示蓝水平渐变色
                'd12: rgb_data <= bar_data[15:0];
                default: 
                      rgb_data <= 16'h22aa;
            endcase
        end
    end
    
`else
    always @(posedge clk) begin
        if(!rst_n)
            rgb_data <= 'h0;
        else begin
            //test vga edge h and w
            if(pos_y <= 0)     
            // if(pos_x <= 0)
                rgb_data <= 'b00000_111111_00000;   //Green
            else if(pos_y >= `VGA_HEIGHT - 1)  
            // else if(pos_x >= `VGA_WIDTH-1)  
                rgb_data <= 'b11111_000000_00000;   //Red
            else 
                rgb_data <= 'b00000_000000_11111;   //Blue
        end        
    end

`endif

endmodule
